/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2025. All rights reserved.
 */
import { CoreTask } from '../../../external/task/core-task.js';
import { TaskContainer } from '../interface/task-container-interface.js';
import { TaskDetails } from '../interface/task-details-interface.js';

export type TaskCreation = {
  provider: () => CoreTask;
  depends: string[];
  details: TaskDetails;
  dependsDefinedByUser: string[];
};

export class LazyTaskContainer implements TaskContainer {
  private readonly _moduleName: string;

  // 已初始化任务
  private _tasks: Map<string, CoreTask> = new Map<string, CoreTask>();

  // 未初始化任务
  private _lazyTasks: Map<string, TaskCreation> = new Map<string, TaskCreation>();

  constructor(moduleName: string) {
    this._moduleName = moduleName;
  }

  registerTask(creation: TaskCreation): void {
    if (this._lazyTasks.has(creation.details.name)) {
      throw new Error(`Duplicate task ${creation.details.name}.`);
    }
    this._lazyTasks.set(creation.details.name, creation);
  }

  addTask(task: CoreTask): void {
    this._tasks.set(task.getName(), task);
  }

  deleteTask(taskName: string): boolean {
    if (this.hasTask(taskName)) {
      return this._tasks.delete(taskName);
    }
    return true;
  }

  hasTask(taskName: string): boolean {
    return this._tasks.has(taskName) || this._lazyTasks.has(taskName);
  }

  getLazyTask(task: string): TaskCreation | undefined {
    return this._lazyTasks.get(task);
  }

  getTask(task: string) {
    return this.findTask(task);
  }

  /**
   * 获取所有任务
   * 仅返回已初始化的task
   */
  getAllTasks(): CoreTask[] {
    return [...this._tasks.values()];
  }

  getTaskPaths(): string[] {
    const tasks = new Set([...this._tasks.keys(), ...this._lazyTasks.keys()]);
    return [...tasks];
  }

  findTask(taskName: string): CoreTask | undefined {
    const creationAction: TaskCreation | undefined = this._lazyTasks.get(taskName);
    if (!creationAction) {
      return this._tasks.get(taskName);
    }
    if (this._tasks.has(taskName)) {
      return this.initializeLazyTask(creationAction, this._tasks.get(taskName));
    }
    return this.initializeLazyTask(creationAction);
  }

  // 需要返回一个taskCA，对于lazy tasks才存在CA
  findTaskCA(taskName: string): TaskCreation | undefined {
    return this._lazyTasks.get(taskName);
  }

  getTaskDepends(taskPath: string): string[] {
    const taskInstance: CoreTask | undefined = this._tasks.get(taskPath);
    if (taskInstance) {
      return this.mergeDepends(this._lazyTasks.get(taskPath), taskInstance);
    }

    const creation: TaskCreation | undefined = this._lazyTasks.get(taskPath);
    if (!creation) {
      throw new Error(`Task ${taskPath} not find.`);
    }
    return creation.depends;
  }

  clearTasks() {
    this._lazyTasks.clear();
    this._tasks.clear();
  }

  private initializeLazyTask(creation: TaskCreation, existTask?: CoreTask): CoreTask {
    const task: CoreTask = existTask ?? creation.provider();
    this._tasks.set(creation.details.name, task);
    return task.setDependsOn(...this.mergeDepends(creation, task));
  }

  private mergeDepends(creation?: TaskCreation, task?: CoreTask) {
    const allDepends = new Set<string>([...(task?.getDependsOn() ?? []), ...(creation?.depends ?? [])]);
    return [...allDepends];
  }
}
